package other.edan.erp.k3;

import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.creekflow.ruleevent.RuleEvent;
import com.rkhd.platform.sdk.creekflow.ruleevent.RuleEventRequest;
import com.rkhd.platform.sdk.creekflow.ruleevent.RuleEventResponse;
import com.rkhd.platform.sdk.data.model.*;
import com.rkhd.platform.sdk.exception.ApiEntityServiceException;
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.model.OperateResult;
import com.rkhd.platform.sdk.model.XObject;
import com.rkhd.platform.sdk.service.XoqlService;
import org.apache.commons.lang.StringUtils;
import other.edan.erp.utils.HCXObjectService;
import other.edan.erp.utils.ResultVo;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 计算【装机信息】模块字段值
 * @Author: 黎炎松
 * @Date: 2024/11/20 15:41
 */
public class CalcInstallInfoField implements RuleEvent {
    private static final Logger LOGGER = LoggerFactory.getLogger();
    private static final XoqlService xoqlService = XoqlService.instance();
    private static final List<String> businessDept = Arrays.asList("00100303", "0010030301", "0010030302", "0010030305"); // 业务发展部 - 部门编码
    private static String LOGGER_MSG = "计算装机信息模块报表字段 ==> ";

    /**
     * 执行触发规则触发事件
     * @param request
     * @return
     * @throws ScriptBusinessException
     */
    @Override
    public RuleEventResponse execute(RuleEventRequest request) throws ScriptBusinessException {
        LOGGER.info(LOGGER_MSG + "执行触发事件");

        // 处理【装机信息】字段
        Long dataId = request.getDataId();
        dealInstallInfoField(dataId);

        RuleEventResponse response = new RuleEventResponse();
        response.setSuccess(true);
        response.setMsg("success");
        return response;
    }

    public static void main(String[] args) {
        HCXObjectService.isLocal = true;
        CalcInstallInfoField calcInstallInfoField = new CalcInstallInfoField();
        //calcInstallInfoField.dealInstallBySalesOut(3552175155649122L);

        calcInstallInfoField.dealInstallInfoField(3571874393840226L);
    }

    /**
     * 根据销售出库id，更新关联的装机信息
     * @param salesOutId
     */
    public void dealInstallBySalesOut(Long salesOutId) {
        try {
            LOGGER.info(LOGGER_MSG + "开始处理出库关联的装机数据");

            // 获取当前销售出库下的SN码
            String sql = "select id from snCode__c where salesOutReceiptDetails__c.salesOutReceipt__c = " + salesOutId;
            String snCodeIds = xoqlService.query(sql).getRecords().stream().map(v -> v.getString("id")).collect(Collectors.joining(","));

            // 获取关联的装机信息
            sql = String.format("select id from installationInfo__c where snCode__c in (%s)", snCodeIds);
            List<JSONObject> installList = xoqlService.query(sql).getRecords();
            LOGGER.info(LOGGER_MSG + "处理出库关联的装机数据 installList: " + installList.size());

            // todo 批量计算待优化
            for (JSONObject install : installList) {
                dealInstallInfoField(install.getLong("id"));
            }
            LOGGER.info(LOGGER_MSG + "处理出库关联的装机数据结束");
        } catch (ApiEntityServiceException e) {
            e.printStackTrace();
            LOGGER.info(LOGGER_MSG + "处理出库关联的装机数据异常：" + e.getMessage());
        }
    }


    /**
     * 处理【装机信息】模块报表字段赋值
     * @param installId
     * @return
     */
    public ResultVo dealInstallInfoField(Long installId) {
        try {
            LOGGER.info(LOGGER_MSG + "开始处理: " + installId);
            InstallationInfo__c install = new InstallationInfo__c();
            install.setId(installId);
            install = HCXObjectService.get(install);

            // 判断SN码
            Long snCodeId = install.getSnCode__c();
            if (snCodeId == null) {
                LOGGER.info(LOGGER_MSG + "装机信息关联的SN码为空，无需处理");
                return ResultVo.success("装机信息关联的SN码为空，无需处理");
            }

            // 根据SN码找到对应的销售出库
            String sql = "select salesOutReceiptDetails__c.salesOutReceipt__c as salesOutId,snCode__c from snCode__c where id = " + snCodeId;
            List<JSONObject> snCodeList = xoqlService.query(sql).getRecords();
            if (snCodeList.size() == 0) {
                LOGGER.info(LOGGER_MSG + "查询关联的销售出库异常");
                return ResultVo.success("查询关联的销售出库异常");
            }
            SalesOutReceipt__c salesOut = new SalesOutReceipt__c();
            salesOut.setId(snCodeList.get(0).getLong("salesOutId"));
            salesOut = HCXObjectService.get(salesOut);
            Long actualDepart = salesOut.getActualSector__c(); // 实际部门

            String processNo = salesOut.getProcessNo__c(); // 超声/检验报单企业微信审批流程编号

            // 实际产品线
            Integer productLine = 0;
            Long productId = install.getProductName__c();
            if (productId != null) {
                Product product = new Product();
                product.setId(productId);
                product = HCXObjectService.get(product);
                productLine = product.getProductLine__c();
            }

            // 获取装机计算字段子表
            sql = "select id,customItem25__c from shippingPersonnelSheet__c where entityType = 3590014698429035 and installationInfo__c = " + installId;
            List<ShippingPersonnelSheet__c> installFieldList = HCXObjectService.queryAll(sql);
            if (installFieldList != null && installFieldList.size() > 0) {

                // 获取外挂表:【部门-岗位关系】,根据产品线进行分组
                Map<Integer, JSONObject> productLineMap = new HashMap<>();
                if (actualDepart != null) {
                    sql = "select id,name,productLine__c,customItem3__c,customItem4__c,departmentName__c from positionRelationship__c where departmentName__c = " + actualDepart;
                    productLineMap = HCXObjectService.queryAllUseXoql(sql).stream().collect(Collectors.toMap(e -> e.getInteger("productLine__c"), e1 -> e1, (e, e1) -> e));
                }
                LOGGER.info(LOGGER_MSG + "productLineMap: " + productLineMap);

                // 获取外挂表:【用户-职级关系】
                String actualInstallers = installFieldList.stream().map(v -> v.getCustomItem25__c().toString()).collect(Collectors.joining(","));
                sql = String.format("select id,name,userName__c,job__c,userName__c,customItem11__c,customItem12__c,customItem13__c,customItem14__c,userLevel__c from userRankRelation__c where userName__c in (%s)", actualInstallers);
                List<UserRankRelation__c> userRankRelationList = HCXObjectService.queryAll(sql);

                // 处理计算字段子表
                LOGGER.info(LOGGER_MSG + "处理明细表");
                for (ShippingPersonnelSheet__c sheet : installFieldList) {
                    UserRankRelation__c userRankRelation = userRankRelationList.stream().filter(v -> Objects.equals(v.getUserName__c(), sheet.getCustomItem25__c())).findFirst().orElse(null);
                    LOGGER.info(LOGGER_MSG + "userRankRelation: " + userRankRelation);
                    dealCalcField(sheet, productLineMap, userRankRelation, productLine, processNo);
                }

                // 保存明细表
                LOGGER.info(LOGGER_MSG + "保存明细表");
                HCXObjectService.updateBatch(installFieldList);
            }

            // 装机获取需要修改的字段
            InstallationInfo__c upInstall = new InstallationInfo__c();
            upInstall.setId(installId);
            upInstall.setBusinessDevelopmentPerformance__c(getBusinessDepart(salesOut.getOriDepartment__c(), salesOut.getSalesman__c(), install)); // 是否为业务发展部业绩
            OperateResult update = HCXObjectService.update(upInstall);

            LOGGER.info(LOGGER_MSG + "update:" + update.getSuccess());
            LOGGER.info(LOGGER_MSG + "处理成功");
            return ResultVo.success("处理成功");
        } catch (ApiEntityServiceException e) {
            e.printStackTrace();
            LOGGER.error(LOGGER_MSG + "处理异常:" + e.getMessage());
            return ResultVo.error("处理异常: " + e.getMessage());
        }
    }

    /**
     * 计算装机计算字段
     * @param upSheet
     * @param productLineMap
     * @param userRankRelation
     * @param productLine
     * @param processNo
     */
    public void dealCalcField(ShippingPersonnelSheet__c upSheet, Map<Integer, JSONObject> productLineMap, UserRankRelation__c userRankRelation, Integer productLine, String processNo) {
        Long actualInstaller = upSheet.getCustomItem25__c(); // 办事处确认业务员/装机人
        /**
         * 超声线省区/区域经理
         * 取值逻辑：
         *      1、如果产品线为“超声”，且“超声/检验报单企业微信审批流程编号”有值，同时满足上述两个条件时，该值为空；
         *      2、如果为产品线为“超声”，根据“实际部门“从“外挂表3”中取值；
         */
        Long csxQyjl = null;
        if (Objects.equals(productLine, 4) && productLineMap.containsKey(productLine) && StringUtils.isBlank(processNo)) {
            csxQyjl = productLineMap.get(productLine).getLong("customItem3__c");
        }
        upSheet.setCustomItem2__c(csxQyjl);

        // 检验线
        Long jyxQyjj = null; // 检验线省区/区域经理
        Long jyxDqjj = null; // 检验线大区经理
        if (Objects.equals(productLine, 5) && productLineMap.containsKey(productLine) && StringUtils.isBlank(processNo)) {
            JSONObject lineObj = productLineMap.get(productLine);
            jyxQyjj = lineObj.getLong("customItem3__c");
            jyxDqjj = lineObj.getLong("customItem4__c");
        }
        upSheet.setCustomItem3__c(jyxQyjj);
        upSheet.setCustomItem4__c(jyxDqjj);

        // 常规线
        Long xxzg = null; // 常规线销售主管/业务发展部省区经理
        Long gjzg = null; // 常规线高级主管/业务发展部区域经理
        Long fzr = null; // 办事处副主任
        Long fzbDqjj = null; // 业务发展部大区经理
        Long pdKhjj = null; // 盆底客户经理
        Long cssKhjj = null; // 超声线客户经理
        Long jyxKhjj = null; // 检验线客户经理
        Long fzbKhjj = null; // 常规线/业务发展部客户经理
        if (userRankRelation != null) {
            String userLevel = userRankRelation.getUserLevel__c(); // 员工级别

            // 常规线销售主管/业务发展部省区经理
            if (userLevel.contains("主管")) {
                xxzg = actualInstaller;
            } else if (StringUtils.isBlank(processNo)) {
                xxzg = userRankRelation.getCustomItem11__c();
            }

            // 常规线高级主管/业务发展部区域经理
            if (userLevel.contains("高级主管")) {
                gjzg = actualInstaller;
            } else if (StringUtils.isBlank(processNo)) {
                gjzg = userRankRelation.getCustomItem12__c();
            }

            // 办事处副主任
            if (userLevel.contains("副主任")) {
                fzr = actualInstaller;
            } else if (StringUtils.isBlank(processNo)) {
                fzr = userRankRelation.getCustomItem13__c();
            }

            // 业务发展部大区经理
            fzbDqjj = userLevel.contains("大区经理") ? actualInstaller : userRankRelation.getCustomItem14__c();

            // 盆底客户经理
            if (userLevel.contains("职员级-盆底")) pdKhjj = actualInstaller;

            // 超声线客户经理
            if (userLevel.contains("职员级-超声")) cssKhjj = actualInstaller;

            // 检验线客户经理
            if (userLevel.contains("职员级-检验")) jyxKhjj = actualInstaller;

            // 常规线/业务发展部客户经理
            if (userLevel.equals("职员级")) fzbKhjj = actualInstaller;
        }
        upSheet.setCustomItem9__c(xxzg);
        upSheet.setCustomItem10__c(gjzg);
        upSheet.setCustomItem11__c(fzr);
        upSheet.setCustomItem12__c(fzbDqjj);
        upSheet.setCustomItem13__c(pdKhjj);
        upSheet.setCustomItem14__c(cssKhjj);
        upSheet.setCustomItem15__c(jyxKhjj);
        upSheet.setCustomItem16__c(fzbKhjj);
    }

    /**
     * 是否为业务发展部业绩 1:是  2: 否
     *
     * @param oriDepartment
     * @param salesman
     * @param install
     * @return
     * @throws ApiEntityServiceException
     */
    public Integer getBusinessDepart(String oriDepartment, Long salesman, InstallationInfo__c install) throws ApiEntityServiceException {

        // 判断
        if (oriDepartment.contains("业务发展部")) {
            // 原部门为“业务发展部”；
            return 1;
        } else if (oriDepartment.contains("办事处") && salesman != null) {
            // 原部门为”办事处“，且业务员所在的部门为 业务发展部
            String sql = "select id,dimDepart.departCode as departCode from user where id = " + salesman;
            List<JSONObject> userList = xoqlService.query(sql).getRecords();
            if (userList.size() > 0 && businessDept.contains(userList.get(0).getString("departCode"))) {
                return 1;
            }
        }

        // 是 民营业绩 & 民营业务员 所需部门为 业务发展部
        Integer privatePerformance = install.getPrivatePerformance__c();
        if (Objects.equals(privatePerformance, 1)) {
            String sql = "select id,dimDepart.departCode as departCode from user where id = " + install.getPrivateSalesman__c();
            List<JSONObject> userList = xoqlService.query(sql).getRecords();
            if (userList.size() > 0 && businessDept.contains(userList.get(0).getString("departCode"))) {
                return 1;
            }
        }

        return 2;
    }


}
